module digital_mixer_rx # (
    parameter IN_WIDTH  = 13,
    parameter NCO_WIDTH = 13,
    parameter PHASE_WIDTH = 16
)
(
    input  wire                                       sys_clk,
    input  wire                                       sys_rst,
    input  wire                                       enable,
    input  wire         [PHASE_WIDTH - 1         :0 ] freq_word,
    input  wire signed  [IN_WIDTH - 1            :0 ] in_data,
    output wire signed  [IN_WIDTH + NCO_WIDTH - 1:0 ] i_data,
    output wire signed  [IN_WIDTH + NCO_WIDTH - 1:0 ] q_data,
    output wire                                       valid
);

wire signed [NCO_WIDTH - 1 :0 ] cos_wave;
wire signed [NCO_WIDTH - 1 :0 ] sin_wave;

wire cos_valid;
wire sin_valid;
wire i_ch_valid;
wire q_ch_valid;

//I channel cos
nco_gen #(
   .DATA_WIDTH(NCO_WIDTH),
   .DATA_COUNT(1024),
   .DATA_COUNT_LOG2(10),
   .PHASE_WIDTH(PHASE_WIDTH),
   .INIT_PHASE({1'd1,1'b1,{(PHASE_WIDTH-2){1'b0}}})
) nco_i (
   .sys_clk (sys_clk),
   .sys_rst (sys_rst),
   .enable  (enable),
   .freq_word (freq_word),

   .out_data (cos_wave),
   .valid    (cos_valid)
);

//I channel mult
mult_sim #(
   .INPUT_WIDTH_A(NCO_WIDTH),
   .INPUT_WIDTH_B(IN_WIDTH),
   .OUTPUT_WIDTH(IN_WIDTH + NCO_WIDTH),
   .DELAY(3)
) mult_i
(
   .sys_clk(sys_clk),
   .sys_rst(sys_rst),
   .enable(cos_valid),
   .data_a(cos_wave),
   .data_b(in_data),
   .data_o(i_data),
   .valid(i_ch_valid)
);

//Q channel sin
nco_gen #(
   .DATA_WIDTH(NCO_WIDTH),
   .DATA_COUNT(1024),
   .DATA_COUNT_LOG2(10),
   .PHASE_WIDTH(PHASE_WIDTH),
   .INIT_PHASE({1'd1,1'b0,{(PHASE_WIDTH-2){1'b0}}})
) nco_q (
   .sys_clk (sys_clk),
   .sys_rst (sys_rst),
   .enable  (enable),
   .freq_word (freq_word),

   .out_data (sin_wave),
   .valid    (sin_valid)
);

//Q channel mult
mult_sim #(
   .INPUT_WIDTH_A(NCO_WIDTH),
   .INPUT_WIDTH_B(IN_WIDTH),
   .OUTPUT_WIDTH(IN_WIDTH + NCO_WIDTH),
   .DELAY(3)
) mult_q
(
   .sys_clk(sys_clk),
   .sys_rst(sys_rst),
   .enable(sin_valid),
   .data_a(sin_wave),
   .data_b(in_data),
   .data_o(q_data),
   .valid(q_ch_valid)
);

assign valid = i_ch_valid && q_ch_valid;

endmodule
